/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.commons.querydsl;

import java.io.Serializable;

import com.querydsl.core.Tuple;
import com.querydsl.core.types.MappingProjection;
import com.querydsl.core.types.Path;
import com.querydsl.sql.RelationalPathBase;

/**
 * @param <T>
 * @param <ID>
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 */
public class EntityProjection<T, ID extends Serializable> extends MappingProjection<T> {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    protected QuerydslHelper<T, ID> helper;
    protected Path<?>[] projectionArgs;

    public EntityProjection(QuerydslHelper<T, ID> helper, RelationalPathBase<T> qvar, Path<?>... projectionArgs) {
        super((Class<? super T>) qvar.getType(), projectionArgs);
        this.helper = helper;
        this.projectionArgs = projectionArgs;
        for (Path<?> path : projectionArgs) {
            helper.isEntityColumn(path);
        }
    }

    @Override
    protected T map(Tuple row) {
        T entity;
        try {
            entity = getType().newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        for (int i = 0; i < projectionArgs.length; i++) {
            Path<?> path = projectionArgs[i];
            Object value = row.get(path);
            helper.setValue(entity, path, value);
        }
        return entity;
    }

}
